/**
 * 响应式hooks
 * - 这个钩子的出入参该怎么设定？
 * - 如何将数据制作成响应式（毕竟普通的操作无法刷新视图）？
 * - 如何使用TS去写，完善其类型？
 * - 如何更好的去优化？
 */

import { useRef } from "react";
import useCreation from "./useCreation";
import useUpdate from "./useUpdate";

/* type Record<K extends keyof any, T> = {
    [P in K]:T
} */

const observer = <T extends Record<string, any>>(initialVal: T, cb: () => void): T => {
  const proxy = new Proxy<T>(initialVal, {
    get(target, key, receiver) {
      const res = Reflect.get(target, key, receiver);
      return typeof res === "object" ? observer(res, cb) : Reflect.get(target, key);
    },
    set(target, key, val) {
      const ret = Reflect.set(target, key, val);
      cb();
      return ret;
    }
  });

  return proxy;
};

function useReactive<T extends Record<string, any>>(initialState: T): T {
  const ref = useRef<T>(initialState);
  const update = useUpdate();

  const state = useCreation(
    () =>
      observer(ref.current, () => {
        update();
      }),
    []
  );

  return state;
}

export default useReactive;
